package com.yuyou.fn.tradingservice.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.github.wens.mybatisplus.toolkit.IdWorker;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.CriteriaUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.settlement.entity.FeeCategory;
import com.yuyou.fn.settlement.entity.RelFeeCategoryIncomeCategory;
import com.yuyou.fn.settlement.service.IFeeCategoryService;
import com.yuyou.fn.settlement.service.IIncomeCategoryService;
import com.yuyou.fn.settlement.service.IRelFeeCategoryIncomeCategoryService;
import com.yuyou.fn.tradingservice.entity.ServiceCategory;
import com.yuyou.fn.tradingservice.mapper.ServiceCategoryMapper;
import com.yuyou.fn.tradingservice.service.IServiceCategoryService;
import com.yuyou.fn.tradingservice.service.IServiceProductService;
import com.yuyou.fn.tradingservice.vo.CategoryCommonVo;
import com.yuyou.fn.tradingservice.vo.CategoryTreeVo;
import com.yuyou.fn.tradingservice.vo.ServiceCategoryTreeVo;
import com.yuyou.fn.tradingservice.vo.ServiceCategoryVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * ServiceCategory 表数据服务层接口实现类
 *
 */
@Service
public class ServiceCategoryServiceImpl extends SuperServiceImpl<ServiceCategoryMapper, ServiceCategory,Long> implements IServiceCategoryService {
    @Resource
    private IFeeCategoryService feeCategoryService;

    @Resource
    private IIncomeCategoryService incomeCategoryService;

    @Resource
    private IServiceProductService serviceProductService;


    @Resource
    private IRelFeeCategoryIncomeCategoryService relFeeCategoryIncomeCategoryService;

    @Override
    public ServiceCategory findDetail(Long categoryId) {
        ServiceCategory serviceCategory=this.findById(categoryId);
        if (serviceCategory.getParentId()!=null && serviceCategory.getParentId()!=0){
            ServiceCategory parent=this.findById(serviceCategory.getParentId());
            serviceCategory.setParentName(parent.getParentName());
        }
        //serviceCategory.setIncomeCategoryName(incomeCategoryService.findById(serviceCategory.getIncomeCategoryId()).getName());
        serviceCategory.setFeeCategoryName(feeCategoryService.findById(serviceCategory.getFeeCategoryId()).getName());
        return serviceCategory;
    }

    @Override
    public void saveCategory(ServiceCategoryVo categoryVo) {


        ServiceCategory category = new ServiceCategory();

        BeanUtils.copyProperties(category,categoryVo);
        if (categoryVo.getParentId()!=null){
            ServiceCategory parentCategory=this.findById(categoryVo.getParentId());
            //category.setParentId();
            category.setParentId(parentCategory.getCategoryId());
            category.setRootId(parentCategory.getRootId());
            category.setLevel(parentCategory.getLevel()+1);
            category.setParentName(parentCategory.getName());
        }else {
            category.setParentId(0L);
            category.setCategoryId(IdWorker.getId());
            category.setRootId(category.getCategoryId());
            category.setLevel(1);
        }

        if (category.getFeeCategoryId()!=null){
            FeeCategory feeCategory=feeCategoryService.findById(category.getFeeCategoryId());
            category.setFeeCategoryName(feeCategory.getName());
            RelFeeCategoryIncomeCategory relFeeCategoryIncomeCategory=relFeeCategoryIncomeCategoryService.findById(feeCategory.getFeeCategoryId());
            if (relFeeCategoryIncomeCategory==null){
                throw  new BusException("所选的成本类型没有对应的收入类型，不可选择");
            }
            FeeCategory parentFeeCategory=feeCategoryService.findById(feeCategory.getParentFeeCategoryId());
            if (parentFeeCategory!=null){
                category.setParentFeeCategoryId(parentFeeCategory.getFeeCategoryId());
                category.setParentFeeCategoryName(parentFeeCategory.getName());
            }
        }else {
            throw new BusException("成本类型必须选择");
        }
      /*  if (category.getIncomeCategoryId()!=null){
            IncomeCategory incomeCategory=incomeCategoryService.findById(category.getIncomeCategoryId());
            category.setIncomeCategoryName(incomeCategory.getName());
        }*/
        category.setCreateTime(TimeUtils.now());
        category.setUpdateTime(TimeUtils.now());
        insertSelective(category);
    }

    @Override
    public List<ServiceCategory> findListByType(Integer type) {
        Example<ServiceCategory> example = ServiceCategory.createExample();
        example.createCriteria().andEqualTo("type", type);
        return this.findListByExample(example);
    }

    @Override
    @Transactional
    public void editCategory(ServiceCategoryVo categoryVo) {


        ServiceCategory serviceCategory=this.findById(categoryVo.getCategoryId());
        if (serviceCategory==null){
            throw  new BusException("查不到该分类信息");
        }
        /*更新供应，课室，需求的分类信息*/
        if (!categoryVo.getName().equals(serviceCategory.getName())){
            serviceProductService.updateCategoryNames(serviceCategory.getName(),categoryVo.getName(),serviceCategory.getCategoryId());
            serviceProductService.updateCategoryName(categoryVo.getName(),serviceCategory.getCategoryId());
        }

        ServiceCategory category = new ServiceCategory();

        BeanUtils.copyProperties(category,categoryVo);


        if (category.getFeeCategoryId()!=null){
            FeeCategory feeCategory=feeCategoryService.findById(category.getFeeCategoryId());
            category.setFeeCategoryName(feeCategory.getName());
            RelFeeCategoryIncomeCategory relFeeCategoryIncomeCategory=relFeeCategoryIncomeCategoryService.findById(feeCategory.getFeeCategoryId());
            if (relFeeCategoryIncomeCategory==null){
                throw  new BusException("所选的成本类型没有对应的收入类型，不可选择");
            }
            FeeCategory parentFeeCategory=feeCategoryService.findById(feeCategory.getParentFeeCategoryId());
            if (parentFeeCategory!=null){
                category.setParentFeeCategoryId(parentFeeCategory.getFeeCategoryId());
                category.setParentFeeCategoryName(parentFeeCategory.getName());
            }
        }
     /*   if (category.getIncomeCategoryId()!=null){
            IncomeCategory incomeCategory=incomeCategoryService.findById(category.getIncomeCategoryId());
            category.setIncomeCategoryName(incomeCategory.getName());
        }*/
        category.setCreateTime(TimeUtils.now());
        category.setUpdateTime(TimeUtils.now());
        updateSelectiveById(category);
    }


    @Override
    public void deleteCategory(Long categoryId) {
        Long productNum=serviceProductService.countServiceProductByCategoryId(categoryId);
        if (productNum.intValue()>0){
            throw new BusException("该分类已存在商品等，不可删除");
        }
        deleteById(categoryId);
    }

    @Override
    public Page<ServiceCategory> findCategoryForPage(ServiceCategoryVo category, int pageNo, int pageSize) {
        Example<ServiceCategory> example = ServiceCategory.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria, category);
        return findPageByExample(example, pageNo, pageSize);
    }

    @Override
    public String findCategoryNameById(Long categoryId) {
        Example<ServiceCategory> example = ServiceCategory.createExample();
        example.selectProperties("name");
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("categoryId",categoryId);
        ServiceCategory category = findOneByExample(example);
        return category == null ? StringUtils.EMPTY : category.getName() ;
    }

    @Override
    public List<ServiceCategory> getChildCategory(Long categoryId) {
        Example<ServiceCategory> example = ServiceCategory.createExample();
        example.createCriteria().andEqualTo("parentId", categoryId);
        return this.findListByExample(example);
    }

    @Override
    public List<ServiceCategory> findCategoryByType(Integer type) {
        Example<ServiceCategory> example = ServiceCategory.createExample();
        example.createCriteria().andEqualTo("type", type);
        return this.findListByExample(example);
    }

    @Override
    public List<Long> getAllChildCategory(Long categoryId) {
        List<Long> categoryIds = new ArrayList<>();
        List<ServiceCategory> categoryList = this.findCategoryByType(this.findById(categoryId).getType());
        return this.getCategoryIds(categoryList, categoryId, categoryIds);
    }

    public List<Long> getCategoryIds(List<ServiceCategory> categoryList, Long pid, List<Long> categoryIds){
        for(ServiceCategory category: categoryList){
            if(category.getParentId() != null) {
                if(category.getParentId().equals(pid)){
                    getCategoryIds(categoryList,category.getCategoryId(), categoryIds);
                    categoryIds.add(category.getCategoryId());
                }
            }
        }
        return categoryIds;
    }

    @Override
    public List<ServiceCategory> findSubCategoryByType(Integer type) {
        Example<ServiceCategory> example = ServiceCategory.createExample();
        example.createCriteria().andEqualTo("type", type);
        return this.findListByExample(example);
    }



    @Override
    public void saveCategoryList(CategoryCommonVo categoryCommonVo, CategoryTreeVo categoryTreeVo) {
        if (categoryTreeVo.getCategoryId()!=null){
            this.deleteByRootId(categoryTreeVo.getCategoryId());
        }
        List<ServiceCategory> serviceCategoryList=new ArrayList<ServiceCategory>();
        Long rootId=null;
        if (categoryTreeVo.getCategoryId()!=null){
            rootId=categoryTreeVo.getCategoryId();
        }else {
            rootId=IdWorker.getId();
        }
        this.assembleData(1,0L,rootId,serviceCategoryList,categoryCommonVo,categoryTreeVo);
        this.insertBatch(serviceCategoryList);
    }


    public void assembleData(Integer level,Long parentId,Long rootId,List<ServiceCategory> serviceCategoryList,CategoryCommonVo categoryCommonVo,CategoryTreeVo  categoryTreeVo){
        ServiceCategory serviceCategory=this.fillServiceCategory(level,parentId,rootId,categoryCommonVo,categoryTreeVo);
        serviceCategoryList.add(serviceCategory);
        if (categoryTreeVo.getCategoryTreeVoList()!=null){
            parentId=serviceCategory.getCategoryId();
            level=serviceCategory.getLevel()+1;
            for (CategoryTreeVo childCategoryTreeVo:categoryTreeVo.getCategoryTreeVoList()){
                /*ServiceCategory childServiceCategory=this.fillServiceCategory(level,parentId,rootId,categoryCommonVo,childCategoryTreeVo);
                serviceCategoryList.add(childServiceCategory);*/
                this.assembleData(level,parentId,rootId,serviceCategoryList,categoryCommonVo,childCategoryTreeVo);
            }
        }
    }
    ServiceCategory fillServiceCategory(Integer level,Long parentId,Long rootId,CategoryCommonVo categoryCommonVo,CategoryTreeVo  categoryTreeVo){
        ServiceCategory serviceCategory=new ServiceCategory();
        BeanUtils.copyProperties(serviceCategory,categoryCommonVo);
        serviceCategory.setName(categoryTreeVo.getName());
        serviceCategory.setCategoryId(categoryTreeVo.getCategoryId());
        serviceCategory.setUpdateTime(TimeUtils.now());
        serviceCategory.setCreateTime(TimeUtils.now());
        serviceCategory.setRootId(rootId);
        serviceCategory.setLevel(level);
        serviceCategory.setParentId(parentId);
        if (serviceCategory.getCategoryId()==null){
            serviceCategory.setCategoryId(IdWorker.getId());
        }
        return serviceCategory;
    }

    @Override
    public void deleteByRootId(Long rootId) {
        if(rootId == null ){
            throw new NullPointerException();
        }
        Example<ServiceCategory> example=ServiceCategory.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("rootId",rootId);
        deleteByExample(example);
    }

    @Override
    public List<ServiceCategory> findOrderByRooIdAndParentId(Integer type) {
        Example<ServiceCategory> example=ServiceCategory.createExample();

        if (type!=null){
            Example.Criteria criteria=example.createCriteria();
            criteria.andEqualTo("type",type);
        }
        example.orderBy("rootId");
        example.orderBy("parentId");
        //List<ServiceCategory> allList=this.findListByExample(example);
       /* for(Iterator<ServiceCategory> it=c.iterator();it.hasNext();){
            Name name=(Name)it.next();
            if(name.getLastName().length()<4)
                it.remove();
            //c.remove(name);  结果不正确
        }*/


        return this.findListByExample(example);
    }

    private List<ServiceCategoryTreeVo> toServiceCategoryTreeVo(List<ServiceCategory> allServiceCategoryList , Map<Long, ServiceCategory> allServiceCategoryMap, Long parentId) {
        List<ServiceCategoryTreeVo> list  = new ArrayList<>(10);
        for(ServiceCategory serviceCategory :  allServiceCategoryList ){
            if(parentId.equals(serviceCategory.getParentId())){
                ServiceCategoryTreeVo serviceCategoryTreeVo = new ServiceCategoryTreeVo();
                serviceCategoryTreeVo.setLabel(serviceCategory.getName());
                serviceCategoryTreeVo.setValue(serviceCategory.getCategoryId());
                serviceCategoryTreeVo.setLevel(serviceCategory.getLevel());
                list.add(serviceCategoryTreeVo);
                List<ServiceCategoryTreeVo> childrenList = toServiceCategoryTreeVo(allServiceCategoryList, allServiceCategoryMap, serviceCategoryTreeVo.getValue());
                if(childrenList.size() > 0 ){
                    serviceCategoryTreeVo.setChildren(childrenList);
                }
            }
        }

        return list;
    }

    @Override
    public List<ServiceCategoryTreeVo> findServiceCategoryTreeVoByType(Integer type) {
        List<ServiceCategory> serviceCategoryList=this.findOrderByRooIdAndParentId(type);
        Map<Long,ServiceCategory> allSerivceCategoryMap =  BeanUtils.toMap(serviceCategoryList, "categoryId");
        List list=this.toServiceCategoryTreeVo(serviceCategoryList,allSerivceCategoryMap,0L);
        return list;
    }

    @Override
    public HashMap<Integer, List<ServiceCategory>> findMapByType() {
        List<ServiceCategory> serviceCategoryList=this.findOrderByRooIdAndParentId(null);
        HashMap<Integer, List<ServiceCategory>> result=new HashMap<Integer, List<ServiceCategory>>();
        for (ServiceCategory serviceCategory:serviceCategoryList){
            List<ServiceCategory> subList=null;
            if (result.containsKey(serviceCategory.getType())){
                subList=result.get(serviceCategory.getType());
            }else {
                subList=new ArrayList<ServiceCategory>();
                result.put(serviceCategory.getType(),subList);
            }
            subList.add(serviceCategory);
        }
        return result;
    }
}